﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BSCMFF.Core.DataAccessLayer;
using System.Collections;

namespace BSCMFF.Core.BusinessLayer
{
    public class BSCTreeListManager
    {
        /*public static List<BSCTreeListItem> GetData()
        {
            List<BSCTreeListItem> list = new List<BSCTreeListItem>();

            BSCEntities context = new BSCEntities();
            List<KPI> kpis = new List<KPI>();
            kpis = (from k in context.KPIs
                    select k).ToList();

            //foreach (KPI k in kpis)
            //{
            //    list.Add(new BSCTreeListItem(k.KPI_ID, k.Name, "KPI", k.Weight, k.Perspective_FK));
            //    //BSCTreeListItem mi = new BSCTreeListItem(k.KPI_ID, k.Name, "KPI", k.Weight, k.Perspective_FK);
            //}

            List<Perspective> persp = new List<Perspective>();
            persp = (from p in context.Perspectives
                     select p).ToList();

            foreach (Perspective p in persp)
            {
                
                list.Add(new BSCTreeListItem(p.Perspective_ID, p.Name, "Perspective", 0, 0));
                //BSCTreeListItem mi = new BSCTreeListItem(k.KPI_ID, k.Name, k.st
            }

           

            list.Add(new BSCTreeListItem(0, "Balanced Scorecard", "tralala", 0, 0));

            //return list2;
            return list;
        }*/

        public static List<BSCTreeListItem> GetDataByDate(DateTime date)
        {
            List<BSCTreeListItem> list = new List<BSCTreeListItem>();

            BSCEntities context = new BSCEntities();

            AddKPIs(date, list, context);

            AddPerspectives(list, context);

            // -- add Main TreeListItem
            list.Add(new BSCTreeListItem(0, "Balanced Scorecard", "bsc", 0, 0));

            return list;
        }

        private static void AddPerspectives(List<BSCTreeListItem> list, BSCEntities context)
        {
            /// -- add perspectives
            List<Perspective> persps = new List<Perspective>();
            persps = (from k in context.Perspectives
                      select k).ToList();

            foreach (Perspective p in persps)
            {
                BSCTreeListItem bli = new BSCTreeListItem();
                bli.ID = "perspective" + p.Perspective_ID.ToString();
                bli.OrigID = p.Perspective_ID;
                bli.Name = p.Name;
                bli.ItemType = "Perspective";
                bli.ParentID = "0"; //root - BSC
                // "perspective" + p.Perspective_ID.ToString();
                //bli.Weight = p.Weight.ToString();

                //bli.Progress = CalculateProgressForPerspective(bli.ID, list); //kp.Progress.ToString();

                Hashtable calculatedValues = CalculateValuesForPerspective(bli.ID, list);

                bli.Progress = calculatedValues["progress"].ToString();
                bli.Performance = calculatedValues["performance"].ToString();
                bli.Start = calculatedValues["start"].ToString();
                bli.Current = "";
                bli.Target = calculatedValues["target"].ToString();
                bli.Min = "0";
                bli.Max = "100";


                //bli.Performance = kp.Performance.ToString();

                list.Add(bli);

                //list.Add(new BSCTreeListItem(p.Perspective_ID, p.Name, "Perspective", p.Weight, 0));
                //MyItem mi = new MyItem(k.KPI_ID, k.Name, k.st
            }
        }

        
        
        private static void AddKPIs(DateTime date, List<BSCTreeListItem> list, BSCEntities context)
        {
            var kpis = (from k in context.KPIs
                        //where k.KPI_ID == 1 || k.KPI_ID == 4 || k.KPI_ID == 12 || k.KPI_ID == 15
                        select k).ToList();

            //List<KPI> kpiss = (from k in context.KPIs.in

            foreach (KPI k in kpis)
            {
                KPI_Progress kp;// = new KPI_Progress();

                //we choose date before KPI was created -> we will take the oldest date .. EDIT: blbost
                if (k.DateCreated > date)
                {
                    //kp = (from progress in context.KPI_Progress
                    //      where progress.KPI_FK == k.KPI_ID && progress.Date == k.DateCreated
                    //      select progress).Take(1).Single();
                    continue;
                }
                //else
                //{
                    //kp = (from progress in context.KPI_Progress
                    //      where progress.KPI_FK == k.KPI_ID && progress.Date == date //progress is updated from previous day by sql agent
                    //      orderby progress.Date descending
                    //      select progress).Take(1).Single();

                    kp = (from progress in context.KPI_Progress
                          where progress.KPI_FK == k.KPI_ID && progress.Date <= date
                          select progress).Take(1).SingleOrDefault();
                //}

                BSCTreeListItem bli = new BSCTreeListItem();
                bli.ID = k.KPI_ID.ToString();
                bli.OrigID = k.KPI_ID;
                bli.Name = k.Name;
                bli.Description = k.Description;
                bli.ItemType = "KPI";
                bli.ParentID = "perspective" + k.Perspective_FK.ToString();
                if (kp != null)
                {
                    bli.Weight = kp.Weight.ToString();
                    bli.Progress = kp.Progress.ToString("#0.00");
                    bli.Performance = kp.Performance.ToString("#0.00");
                    // bli.Progress = kp.Progress.ToString();

                    bli.Start = kp.Start_Value.ToString();
                    bli.Current = kp.Current_Value.ToString();
                    bli.Target = kp.Target_Value.ToString();
                    bli.Min = kp.Min.ToString();
                    bli.Max = kp.Max.ToString();
                }

                list.Add(bli);
                //list.Add(new BSCTreeListItem(k.KPI_ID, k.Name, "KPI", kp.Weight, k.Perspective_FK));
                //BSCTreeListItem mi = new BSCTreeListItem(k.KPI_ID, k.Name, "KPI", k.Weight, k.Perspective_FK);

            }
        }

        private static string CalculateProgressForPerspective(string p, List<BSCTreeListItem> list)
        {
            int weights = 0;
            double progress = 0;

            foreach (BSCTreeListItem l in list)
            {
                if (l.ParentID == p)
                {
                    weights += Convert.ToInt32(l.Weight);
                    progress += Convert.ToDouble(l.Progress) * Convert.ToInt32(l.Weight);
                }
            }

            return weights == 0 ? "0" : Convert.ToDecimal(progress / weights).ToString("#0.00");
        }

        private static Hashtable CalculateValuesForPerspective(string p, List<BSCTreeListItem> list)
        {
            int weights = 0;
            double progress = 0;
            double performance = 0;
            double start = 0;
            double target = 0;

            foreach (BSCTreeListItem l in list)
            {
                if (l.ParentID == p)
                {
                    weights += Convert.ToInt32(l.Weight);
                    progress += Convert.ToDouble(l.Progress) * Convert.ToInt32(l.Weight);
                    performance += Convert.ToDouble(l.Performance) * Convert.ToInt32(l.Weight);
                    start += Convert.ToDouble(l.Start) * Convert.ToInt32(l.Weight);
                    target += Convert.ToDouble(l.Target) * Convert.ToInt32(l.Weight);
                }
            }

            Hashtable ht = new Hashtable();
            if(weights == 0)
            {
                ht["progress"] = "0";
                ht["performance"] = "0";
                ht["start"] = "0";
                ht["target"] = "0";
            }
            else
            {                
                ht["progress"] = Convert.ToDecimal(progress / weights).ToString("#0.00");
                ht["performance"] = Convert.ToDecimal(performance / weights).ToString("#0.00");
                ht["start"] = Convert.ToDecimal(start / weights).ToString("#0.00");
                ht["target"] = Convert.ToDecimal(target / weights).ToString("#0.00");
            }
            return ht;
        }

    
    }
}
